package br.ufrn.dimap.serializer;

import br.ufrn.dimap.processDsl.Activity;
import br.ufrn.dimap.processDsl.Artifact;
import br.ufrn.dimap.processDsl.ArtifactElement;
import br.ufrn.dimap.processDsl.CheckItem;
import br.ufrn.dimap.processDsl.Checklist;
import br.ufrn.dimap.processDsl.Concept;
import br.ufrn.dimap.processDsl.Discipline;
import br.ufrn.dimap.processDsl.Example;
import br.ufrn.dimap.processDsl.Guideline;
import br.ufrn.dimap.processDsl.Iteration;
import br.ufrn.dimap.processDsl.Model;
import br.ufrn.dimap.processDsl.Phase;
import br.ufrn.dimap.processDsl.Practice;
import br.ufrn.dimap.processDsl.ProcessDslPackage;
import br.ufrn.dimap.processDsl.Reference;
import br.ufrn.dimap.processDsl.Report;
import br.ufrn.dimap.processDsl.Roadmap;
import br.ufrn.dimap.processDsl.Role;
import br.ufrn.dimap.processDsl.RoleElement;
import br.ufrn.dimap.processDsl.Step;
import br.ufrn.dimap.processDsl.Task;
import br.ufrn.dimap.processDsl.Template;
import br.ufrn.dimap.services.ProcessDslGrammarAccess;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticNodeProvider.INodesForEObjectProvider;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;

@SuppressWarnings("restriction")
public class AbstractProcessDslSemanticSequencer extends AbstractSemanticSequencer {

	@Inject
	protected ProcessDslGrammarAccess grammarAccess;
	
	@Inject
	protected ISemanticSequencerDiagnosticProvider diagnosticProvider;
	
	@Inject
	protected ITransientValueService transientValues;
	
	@Inject
	@GenericSequencer
	protected Provider<ISemanticSequencer> genericSequencerProvider;
	
	protected ISemanticSequencer genericSequencer;
	
	
	@Override
	public void init(ISemanticSequencer sequencer, ISemanticSequenceAcceptor sequenceAcceptor, Acceptor errorAcceptor) {
		super.init(sequencer, sequenceAcceptor, errorAcceptor);
		this.genericSequencer = genericSequencerProvider.get();
		this.genericSequencer.init(sequencer, sequenceAcceptor, errorAcceptor);
	}
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == ProcessDslPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case ProcessDslPackage.ACTIVITY:
				if(context == grammarAccess.getActivityRule()) {
					sequence_Activity(context, (Activity) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.ARTIFACT:
				if(context == grammarAccess.getArtifactRule()) {
					sequence_Artifact(context, (Artifact) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.ARTIFACT_ELEMENT:
				if(context == grammarAccess.getArtifactElementRule()) {
					sequence_ArtifactElement(context, (ArtifactElement) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.CHECK_ITEM:
				if(context == grammarAccess.getCheckItemRule()) {
					sequence_CheckItem(context, (CheckItem) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.CHECKLIST:
				if(context == grammarAccess.getChecklistRule()) {
					sequence_Checklist(context, (Checklist) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.CONCEPT:
				if(context == grammarAccess.getConceptRule()) {
					sequence_Concept(context, (Concept) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.DISCIPLINE:
				if(context == grammarAccess.getDisciplineRule()) {
					sequence_Discipline(context, (Discipline) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.EXAMPLE:
				if(context == grammarAccess.getExampleRule()) {
					sequence_Example(context, (Example) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.GUIDELINE:
				if(context == grammarAccess.getGuidelineRule()) {
					sequence_Guideline(context, (Guideline) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.ITERATION:
				if(context == grammarAccess.getIterationRule()) {
					sequence_Iteration(context, (Iteration) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.MODEL:
				if(context == grammarAccess.getModelRule()) {
					sequence_Model(context, (Model) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.PHASE:
				if(context == grammarAccess.getPhaseRule()) {
					sequence_Phase(context, (Phase) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.PRACTICE:
				if(context == grammarAccess.getPracticeRule()) {
					sequence_Practice(context, (Practice) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.PROCESS:
				if(context == grammarAccess.getProcessRule()) {
					sequence_Process(context, (br.ufrn.dimap.processDsl.Process) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.REFERENCE:
				if(context == grammarAccess.getReferenceRule()) {
					sequence_Reference(context, (Reference) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.REPORT:
				if(context == grammarAccess.getReportRule()) {
					sequence_Report(context, (Report) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.ROADMAP:
				if(context == grammarAccess.getRoadmapRule()) {
					sequence_Roadmap(context, (Roadmap) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.ROLE:
				if(context == grammarAccess.getRoleRule()) {
					sequence_Role(context, (Role) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.ROLE_ELEMENT:
				if(context == grammarAccess.getRoleElementRule()) {
					sequence_RoleElement(context, (RoleElement) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.STEP:
				if(context == grammarAccess.getStepRule()) {
					sequence_Step(context, (Step) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.TASK:
				if(context == grammarAccess.getTaskRule()) {
					sequence_Task(context, (Task) semanticObject); 
					return; 
				}
				else break;
			case ProcessDslPackage.TEMPLATE:
				if(context == grammarAccess.getTemplateRule()) {
					sequence_Template(context, (Template) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING tasks+=[Task|ID]* nextActivity+=[Activity|ID]?)
	 */
	protected void sequence_Activity(EObject context, Activity semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (artifacts=[Artifact|ID] (pinType='input' | pinType='output') (variability='mandatory' | variability='opcional')?)
	 */
	protected void sequence_ArtifactElement(EObject context, ArtifactElement semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING domain=[Discipline|ID]? purpose=STRING?)
	 */
	protected void sequence_Artifact(EObject context, Artifact semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID previous=[CheckItem|ID]?)
	 */
	protected void sequence_CheckItem(EObject context, CheckItem semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID checkItems+=CheckItem*)
	 */
	protected void sequence_Checklist(EObject context, Checklist semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Concept(EObject context, Concept semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.CONCEPT__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.CONCEPT__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.CONCEPT__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.CONCEPT__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getConceptAccess().getNameIDTerminalRuleCall_2_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getConceptAccess().getDescriptionSTRINGTerminalRuleCall_4_0(), semanticObject.getDescription());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     name=STRING
	 */
	protected void sequence_Discipline(EObject context, Discipline semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.DISCIPLINE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.DISCIPLINE__NAME));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getDisciplineAccess().getNameSTRINGTerminalRuleCall_1_0(), semanticObject.getName());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Example(EObject context, Example semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.EXAMPLE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.EXAMPLE__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.EXAMPLE__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.EXAMPLE__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getExampleAccess().getNameIDTerminalRuleCall_2_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getExampleAccess().getDescriptionSTRINGTerminalRuleCall_4_0(), semanticObject.getDescription());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Guideline(EObject context, Guideline semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.GUIDELINE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.GUIDELINE__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.GUIDELINE__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.GUIDELINE__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getGuidelineAccess().getNameIDTerminalRuleCall_2_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getGuidelineAccess().getDescriptionSTRINGTerminalRuleCall_4_0(), semanticObject.getDescription());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING ativitys+=Activity*)
	 */
	protected void sequence_Iteration(EObject context, Iteration semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     process+=Process
	 */
	protected void sequence_Model(EObject context, Model semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING iterations+=Iteration*)
	 */
	protected void sequence_Phase(EObject context, Phase semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Practice(EObject context, Practice semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.PRACTICE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.PRACTICE__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.PRACTICE__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.PRACTICE__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getPracticeAccess().getNameIDTerminalRuleCall_2_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getPracticeAccess().getDescriptionSTRINGTerminalRuleCall_4_0(), semanticObject.getDescription());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         name=STRING 
	 *         (
	 *             disciplines+=Discipline* | 
	 *             roles+=Role* | 
	 *             artifacts+=Artifact* | 
	 *             tasks+=Task* | 
	 *             (
	 *                 guidances+=Checklist | 
	 *                 guidances+=Concept | 
	 *                 guidances+=Example | 
	 *                 guidances+=Guideline | 
	 *                 guidances+=Practice | 
	 *                 guidances+=Reference | 
	 *                 guidances+=Report | 
	 *                 guidances+=Roadmap | 
	 *                 guidances+=Template
	 *             )*
	 *         )* 
	 *         (lifecyleElement+=Phase | lifecyleElement+=Iteration | lifecyleElement+=Activity)*
	 *     )
	 */
	protected void sequence_Process(EObject context, br.ufrn.dimap.processDsl.Process semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Reference(EObject context, Reference semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.REFERENCE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.REFERENCE__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.REFERENCE__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.REFERENCE__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getReferenceAccess().getNameIDTerminalRuleCall_2_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getReferenceAccess().getDescriptionSTRINGTerminalRuleCall_4_0(), semanticObject.getDescription());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Report(EObject context, Report semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.REPORT__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.REPORT__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.REPORT__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.REPORT__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getReportAccess().getNameIDTerminalRuleCall_2_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getReportAccess().getDescriptionSTRINGTerminalRuleCall_4_0(), semanticObject.getDescription());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Roadmap(EObject context, Roadmap semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.ROADMAP__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.ROADMAP__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.ROADMAP__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.ROADMAP__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getRoadmapAccess().getNameIDTerminalRuleCall_2_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getRoadmapAccess().getDescriptionSTRINGTerminalRuleCall_4_0(), semanticObject.getDescription());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (roles=[Role|ID] (primacy='primary' | primacy='additional'))
	 */
	protected void sequence_RoleElement(EObject context, RoleElement semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Role(EObject context, Role semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.ROLE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.ROLE__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.ROLE__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.ROLE__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getRoleAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getRoleAccess().getDescriptionSTRINGTerminalRuleCall_3_0(), semanticObject.getDescription());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID previous=[Step|ID]?)
	 */
	protected void sequence_Step(EObject context, Step semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         name=ID 
	 *         description=STRING 
	 *         discipline=[Discipline|ID]? 
	 *         purpose=STRING? 
	 *         rolesElement+=RoleElement* 
	 *         artifactsElement+=ArtifactElement* 
	 *         steps+=Step*
	 *     )
	 */
	protected void sequence_Task(EObject context, Task semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID description=STRING)
	 */
	protected void sequence_Template(EObject context, Template semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.TEMPLATE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.TEMPLATE__NAME));
			if(transientValues.isValueTransient(semanticObject, ProcessDslPackage.Literals.TEMPLATE__DESCRIPTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ProcessDslPackage.Literals.TEMPLATE__DESCRIPTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getTemplateAccess().getNameIDTerminalRuleCall_2_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getTemplateAccess().getDescriptionSTRINGTerminalRuleCall_4_0(), semanticObject.getDescription());
		feeder.finish();
	}
}
